﻿using Lanbt.Core.Entity.Constant;
using Lanbt.Core.Entity.Enums;
using Lanbt.Core.Service.Quartz.Job.Model;
using Lanbt.Core.Utility;
using Lanbt.Core.Utility.Helper;
using Lanbt.Core.Utility.Extent;
using Newtonsoft.Json;
using Quartz;
using System.Reflection.Metadata;
using System.Text;
using System.Web;
using Lanbt.Core.Entity.Dto;

namespace Lanbt.Core.Service.Quartz.Job
{
    public class APIJob : JobBase<LogUrlModel>
    {
        private readonly IHttpClientFactory _httpClientFactory;
        public APIJob() :base(new LogUrlModel())
        {
            _httpClientFactory = (IHttpClientFactory)GlobalContext.ServiceProvider.GetService(typeof(IHttpClientFactory));
        }

        public override async Task NextExecute(IJobExecutionContext context)
        {
            HttpContent httpContent = null;
            HttpResponseMessage response = null;
            try
            {
                var dataMap = context.MergedJobDataMap;

                var apiUrl = dataMap.GetString(JobParamConstant.APIURL)!;
                var httpMethod = (QuartzEnums.APIHttpMethod)dataMap.GetInt(JobParamConstant.APIHTTPMETHOD);
                var headString = dataMap.GetString(JobParamConstant.HEAD);
                var heads = headString.IsNotNullOrEmpty() ? JsonConvert.DeserializeObject<Dictionary<string,string>>(headString.Trim()) : null;
                var body = dataMap.GetString(JobParamConstant.FORMBODY);

                LogInfo.Url = apiUrl;
                LogInfo.RequestType = httpMethod.ToString();
                LogInfo.Parameters = body;

                using (var client = _httpClientFactory.CreateClient())
                {
                    if(heads != null)
                    {
                        foreach (var item in heads)
                        {
                            client.DefaultRequestHeaders.Remove(item.Key);
                            client.DefaultRequestHeaders.TryAddWithoutValidation(item.Key, item.Value);
                        }
                    }

                    if (body.IsNotNullOrEmpty())
                    {
                        httpContent = new StringContent(body,Encoding.UTF8,"application/json");
                    }

                    switch (httpMethod)
                    {
                        case QuartzEnums.APIHttpMethod.GET:
                            response = await client.GetAsync(apiUrl);
                            break;
                        case QuartzEnums.APIHttpMethod.POST:
                            response = await client.PostAsync(apiUrl, httpContent);
                            break;
                        case QuartzEnums.APIHttpMethod.PUT:
                            response = await client.PutAsync(apiUrl, httpContent);
                            break;
                        case QuartzEnums.APIHttpMethod.DELETE:
                            response = await client.DeleteAsync(apiUrl);
                            break;
                    }

                    
                    if (!response.IsSuccessStatusCode)
                    {
                        await WarningAsync(LogInfo.JobName, $"{LogInfo.JobName}——地址：【{apiUrl}】访问失败——错误信息：{response.RequestMessage}", MailLevel);
                    }
                    else
                    {
                        try
                        {
                            var result = await response.Content.ReadAsStringAsync();
                            var httpResult = result.JsonToObject<ResultOutput>();
                            if (httpResult.Success)
                            {
                                LogInfo.Result = $"<span class='result'>{httpResult.Result}</span>";
                            }
                            else
                            {
                                LogInfo.ErrorMsg = $"<span class='error'>{httpResult.ErrorMsg}</span>";
                                await ErrorAsync(LogInfo.JobName, new Exception(httpResult.ErrorMsg), LogInfo.ToJson(), MailLevel);
                                context.JobDetail.JobDataMap[JobParamConstant.EXCEPTION] = $"<div class='err-time'>{LogInfo.BeginTime}</div>{LogInfo.ToJson()}";
                            }
                        }
                        catch (Exception ex)
                        {
                            LogInfo.ErrorMsg = $"<span class='error'>{ex.Message}</span>";
                            await ErrorAsync(LogInfo.JobName, ex,"出现异常", MailLevel);
                        }
                    }
                }
            }
            finally
            {
                response?.Dispose();
                httpContent?.Dispose();
            }
        }
    }
}
